#include <iostream>
#include "MysqlOperation.h"
#include "ConnectPool.h"

using namespace std;

/*
MySQL数据库是一个典型的C/S结构，即：客户端和服务器端。
如果我们部署好了MySQL服务器，想要在客户端访问服务器端的数据，
在编写程序的时候就可以通过官方提供的C语言的API来实现。
*/

//	简单测试一下数据库是否可以正常操作
void query() 
{
	MysqlOperation conn;
	conn.connect("root", "123456", "mydb", "127.0.0.1");
	string sql = "insert into users value(5,'meinv',17,'98726543');";
	bool res = conn.update(sql);
	cout << res << "  " << sql.c_str() << endl;
	sql = "select * from users;";
	cout << conn.query(sql) <<"  " << sql.c_str() << endl;

	//遍历结果集
	while (conn.next())
	{
		cout << conn.value(0).c_str() << ", "
			 << conn.value(1).c_str() << ", "
			 << conn.value(2).c_str() << ", "
			 << conn.value(3).c_str() << ", " << endl;
	}
}

//	分两种情况测试：第一种单线程，第二种多线程
//	不使用连接池
void test_op1(int begin, int end) 
{
	for (int i = begin; i < end; i++) 
	{
		MysqlOperation conn;
		conn.connect("root", "123456", "mydb", "127.0.0.1");
		char sql[1024] = { 0 };
		sprintf(sql, "insert into users value(%d,'meinv',18,'98726543');", i);
		cout << conn.update(sql) << sql << endl;
	}
}
//	使用连接池
void test_op2(ConnectPool* pool, int begin, int end)
{
	for (int i = begin; i < end; i++)
	{
		shared_ptr<MysqlOperation> conn = pool->get_connection();
		char sql[1024] = { 0 };
		sprintf(sql, "insert into users value(%d,'meinv',18,'98726543');", i);
		cout << conn->update(sql) << sql << endl;
	}
}
//	单线程测试函数
void test1() {
#if 0
	steady_clock::time_point begin = steady_clock::now();
	test_op1(0, 5000);
	steady_clock::time_point end = steady_clock::now();
	auto time = end - begin;
	cout << "非连接池，单线程，用时：" << time.count() << " 纳秒 "
		<< time.count() / 1000000 << " 毫秒" << endl;

	//	非连接池，单线程，用时：26409797700 纳秒 26409 毫秒

#else
	ConnectPool* pool = ConnectPool::get_connect_pool();
	steady_clock::time_point begin = steady_clock::now();
	test_op2(pool, 5000, 10000);
	steady_clock::time_point end = steady_clock::now();
	auto time = end - begin;
	cout << "连接池，单线程，用时：" << time.count() << " 纳秒 "
		<< time.count() / 1000000 << " 毫秒" << endl;

	//	连接池，单线程，用时：7440440300 纳秒 7440 毫秒

#endif
}

//	多线程：使用/不使用连接池
void test2() 
{
#if 1
	ConnectPool* pool = ConnectPool::get_connect_pool();
	steady_clock::time_point begin = steady_clock::now();
	thread t1(test_op2, pool, 5000, 6000);
	thread t2(test_op2, pool, 6000, 7000);
	thread t3(test_op2, pool, 7000, 8000);
	thread t4(test_op2, pool, 8000, 9000);
	thread t5(test_op2, pool, 9000, 10000);
	t1.join();
	t2.join();
	t3.join();
	t4.join();
	t5.join();
	steady_clock::time_point end = steady_clock::now();
	auto time = end - begin;
	cout << "连接池，多线程，用时：" << time.count() << " 纳秒 "
		<< time.count() / 1000000 << " 毫秒" << endl;
	//	连接池，多线程，用时：3409797700 纳秒 3409 毫秒

#else
	MysqlOperation conn;
	cout << conn.connect("root", "123456", "mydb", "127.0.0.1") << endl;
	steady_clock::time_point begin = steady_clock::now();
	thread t1(test_op1, 0, 1000);
	thread t2(test_op1, 1000, 2000);
	thread t3(test_op1, 2000, 3000);
	thread t4(test_op1, 3000, 4000);
	thread t5(test_op1, 4000, 5000);
	t1.join();
	t2.join();
	t3.join();
	t4.join();
	t5.join();
	steady_clock::time_point end = steady_clock::now();
	auto time = end - begin;
	cout << "非连接池，多线程，用时：" << time.count() << " 纳秒 "
		<< time.count() / 1000000 << " 毫秒" << endl;

	//	非连接池，多线程，用时：8309134400 纳秒 8309 毫秒

#endif
}

int main()
{
	//query();
	//test1();
	test2();
	return 0;
}
